package com.douban.business;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.core.sax.ElementNode;
import org.apache.xerces.xni.Augmentations;
import org.apache.xerces.xni.QName;
import org.apache.xerces.xni.XMLAttributes;
import org.apache.xerces.xni.XMLString;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.parser.XMLInputSource;
import org.apache.xerces.xni.parser.XMLParserConfiguration;
import org.cyberneko.html.HTMLConfiguration;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.UserDataHandler;

import com.core.sax.SaxHandler;

/**
 * This handler should save tree structures for different recommendation types
 * 
 * The tree structure is retrieved from a list of predefined template files
 * 
 * @author SELuoc
 * 
 */
public class DoubanRecsTemplateHandler extends SaxHandler {

	final static String GROUP_TOPIC = "grouptopic.template";
	final static String DIARY = "diary.template";
	final static String ARTICLE = "article.template";
	final static String PHOTO = "photo.template";
	final static String ALBUM = "album.template";

	final static String[] REC_TYPES = { GROUP_TOPIC, DIARY, ARTICLE, PHOTO, ALBUM };
	private static DoubanRecsTemplateHandler singleton = null;

	private String parsingType = null;
	private ElementNode currentNode = null;

	private Map recTypeMap = new HashMap();
	
	private boolean isInitialized = false;

	private DoubanRecsTemplateHandler() {
		super();
	}

	public static final DoubanRecsTemplateHandler getInstance() {
		if (singleton == null) {
			singleton = new DoubanRecsTemplateHandler();
		}
		
		return singleton;
	}

	public void initialize() throws Exception {
		if(isInitialized){
			return;
		}
		
		for (int i = 0; i < REC_TYPES.length; i++) {
			currentNode = null;
			parsingType = REC_TYPES[i];
			Node tr = new ElementNode(parsingType);
			recTypeMap.put(REC_TYPES[i], tr);			
			// init a reader
			XMLParserConfiguration parser = new HTMLConfiguration();			
			// set singleton as a handler
			parser.setDocumentHandler(singleton);
			// start to parse
			XMLInputSource source = new XMLInputSource(null, "C:\\OtherDevelopments\\EclipseWorkspace\\TempApplication\\test\\rec"+REC_TYPES[i], null);
			parser.parse(source);
		}
	}

	public void startElement(QName element, XMLAttributes attrs,
			Augmentations augs) {
		
		if(element.rawname!=null&&
				(element.rawname.equalsIgnoreCase("HTML")||
						element.rawname.equalsIgnoreCase("HEAD")||
						element.rawname.equalsIgnoreCase("BODY"))
				){
			return;
		}
		
		if(currentNode == null){
			currentNode = (ElementNode) recTypeMap.get(parsingType);
		}

		ElementNode newNode = new ElementNode(element.rawname);
		for(int i=0;i<attrs.getLength();i++){
			newNode.setAttribute(attrs.getQName(i), attrs.getValue(i));
		}
		currentNode.appendChild(newNode);
		currentNode = newNode;
//		if(element.)
		// node.set
	}

	public void endElement(QName element, Augmentations augs) {
		if(currentNode!=null){
			currentNode = (ElementNode)currentNode.getParentNode();
		}
	}

	public void characters(XMLString text, Augmentations augs) {
		if(currentNode!=null){
			currentNode.setTextContent(text.toString());
		}
	}
	
	public Map getMap(){
		if(!isInitialized){
			try {
				initialize();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return recTypeMap;
	}
	
	public boolean isInitialized() {
		return isInitialized;
	}
}